package com.chucang.shucang.auth.support.password;

import cn.hutool.core.text.CharSequenceUtil;
import com.chucang.shucang.auth.support.base.OAuth2ResourceOwnerBaseAuthenticationConverter;
import com.chucang.shucang.common.base.constant.SecurityConstant;
import com.chucang.shucang.common.security.utils.OAuth2EndpointUtil;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Set;

/**
 * @author flitsneak
 * @email flitsneak@gmail.com
 * @date 2022/9/15 20:46
 * @description 密码模式转换
 */
public class OAuth2ResourceOwnerPasswordAuthenticationConverter extends OAuth2ResourceOwnerBaseAuthenticationConverter<OAuth2ResourceOwnerPasswordAuthenticationToken> {
    /**
     * 支持密码模式
     *
     * @param grantType 授权类型
     */
    @Override
    public boolean support(String grantType) {
        return AuthorizationGrantType.PASSWORD.getValue().equals(grantType);
    }

    @Override
    public OAuth2ResourceOwnerPasswordAuthenticationToken buildToken(Authentication clientPrincipal,
                                                                     Set<String> requestedScopes, Map<String, Object> additionalParameters) {
        return new OAuth2ResourceOwnerPasswordAuthenticationToken(AuthorizationGrantType.PASSWORD, clientPrincipal,
                requestedScopes, additionalParameters);
    }

    /**
     * 校验扩展参数 密码模式密码必须不为空
     *
     * @param request 参数列表
     */
    @Override
    public void checkParams(HttpServletRequest request) {
        MultiValueMap<String, String> parameters = OAuth2EndpointUtil.getParameters(request);
        // username (REQUIRED)
        String username;
        String SMS_INFO;
        if (CharSequenceUtil.isBlank(parameters.getFirst(SecurityConstant.SMS_PARAMETER_NAME))) {
            username = parameters.getFirst(SecurityConstant.USERNAME);
            SMS_INFO = SecurityConstant.USERNAME;
        } else {
            username = parameters.getFirst(SecurityConstant.SMS_PARAMETER_NAME);
            SMS_INFO = SecurityConstant.SMS_PARAMETER_NAME;
        }
        if (!StringUtils.hasText(username)) {
            OAuth2EndpointUtil.throwError(OAuth2ErrorCodes.INVALID_REQUEST, SMS_INFO,
                    OAuth2EndpointUtil.ACCESS_TOKEN_REQUEST_ERROR_URI);
        }

        // password (REQUIRED)
        String password = parameters.getFirst(OAuth2ParameterNames.PASSWORD);
        if (!StringUtils.hasText(password) || parameters.get(OAuth2ParameterNames.PASSWORD).size() != 1) {
            OAuth2EndpointUtil.throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.PASSWORD,
                    OAuth2EndpointUtil.ACCESS_TOKEN_REQUEST_ERROR_URI);
        }
    }
}
